package com.lanchetech.admin.service.impl;

import com.baidu.fsg.uid.utils.validateUtil.ValidateParam;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.lanchetech.bean.redission.LockCenter;
import com.lanchetech.admin.service.AdvancePaymentService;
import com.lanchetech.admin.task.AgreementSigningTask;
import com.lanchetech.bean.request.GoodsCardReq;
import com.lanchetech.bean.response.BasePageResp;
import com.lanchetech.bean.response.BaseResp;
import com.lanchetech.bean.response.ResultData;
import com.lanchetech.bean.util.PageHelpUtil;
import com.lanchetech.bean.vo.AgreementSigningReq;
import com.lanchetech.bean.vo.AgreementSigningVo;
import com.lanchetech.common.enums.ResultCode;
import com.lanchetech.common.exception.ResultCodeException;
import com.lanchetech.dao.AgreementSigningMapper;
import com.lanchetech.dao.GoodsCardMapper;
import com.lanchetech.dao.ShopMapper;
import com.lanchetech.entity.AgreementSigning;
import com.lanchetech.entity.GoodsCard;
import com.lanchetech.entity.Shop;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

@Service
public class AdvancePaymentServiceImpl implements AdvancePaymentService {

    @Autowired
    GoodsCardMapper goodsCardMapper;
    @Autowired
    AgreementSigningMapper agreementSigningMapper;
    @Autowired
    ShopMapper shopMapper;
    @Autowired
    private AgreementSigningTask agreementSigningTask;

    private final static Logger logger = LoggerFactory.getLogger(AdvancePaymentServiceImpl.class);

    @Override
    public ResultData<BasePageResp<GoodsCard>> getGoodsCardList(GoodsCardReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<GoodsCard> goodsCardList = goodsCardMapper.getGoodsCardList(req);
        BeanUtils.copyProperties(GoodsCard.class, goodsCardList);
        return PageHelpUtil.buildPage(goodsCardList, page);
    }

    @Override
    public BaseResp editGoodsCard(GoodsCard goodsCard) {
        BaseResp baseResp = new BaseResp();
        try {
            // 有ID是修改  无ID是创建
            if (null != goodsCard.getId()) {
                // 查找当前卡有无开启  如:开启中 卡无法进行修改
                GoodsCard card = goodsCardMapper.findOneById(goodsCard.getId());
                if (card.getStatus() == 1) {
                    throw new ResultCodeException(ResultCode.AFTER_OPENING_EDIT);
                }
                // 编辑
                goodsCard.setUpdateAt(new Date());
                goodsCardMapper.updateGoodsCard(goodsCard);
            } else {
                // 创建
                goodsCard.setCreatedAt(new Date());
                goodsCardMapper.editGoodsCard(goodsCard);
            }
            return new BaseResp();
        } catch (ResultCodeException e) {
            baseResp.setResultCode(e.getResultCode());
            return baseResp;
        }
    }

    @Override
    public BaseResp deletedCard(Long id) {
        GoodsCard goodsCard = goodsCardMapper.findOneById(id);
        BaseResp baseResp = new BaseResp();
        try {
            if (null == goodsCard) {
                throw new ResultCodeException(ResultCode.FAIL);
            }
            goodsCard.setDeleted((byte) 1);
            goodsCardMapper.updateGoodsCard(goodsCard);
            return baseResp;
        } catch (ResultCodeException e) {
            baseResp.setResultCode(e.getResultCode());
            return baseResp;
        }
    }

    @Override
    public BaseResp apply(AgreementSigning agreementSigning) {
        // 校验参数
        BaseResp baseResp = new BaseResp();
        try {
            // 是否已申请
            AgreementSigning signing = agreementSigningMapper.findOneByPhone(agreementSigning.getPhone());
            if (signing != null && signing.getStatus() == 1) {
                throw new ResultCodeException(ResultCode.SUBMIT_SUCCESS);
            }
            // 门店/商家 是否存在
            Shop shop = shopMapper.findOneByPhone(agreementSigning.getPhone());
            if (shop == null) {
                throw new ResultCodeException(ResultCode.SHOP_NOT_EXIST);
            }
            // 校验
            checks(agreementSigning);
            // 查找金额对应卡等级ID
            Long goodsCardId = goodsCardMapper.getGoodsCardByAmount(agreementSigning.getSigningAmount());
            if (goodsCardId == 0) {
                throw new ResultCodeException(ResultCode.CREATE_CARD_LEVEL);
            }
            agreementSigning.setGoodsCardId(goodsCardId);
            agreementSigning.setStatus((byte) 1);
            agreementSigningMapper.save(agreementSigning);
        } catch (ResultCodeException e) {
            baseResp.setResultCode(e.getResultCode());
        }
        return baseResp;
    }

    // 最低标准
    private static final BigDecimal amount = BigDecimal.valueOf(2000);

    private void checks(AgreementSigning agreementSigning) throws ResultCodeException {
        // 身份证校验
        if (!ValidateParam.valIDCard(agreementSigning.getIdCard())) {
            throw new ResultCodeException(ResultCode.ID_CARD_ERROR);
        }
        // 手机号校验
        if (!ValidateParam.checkPhone(agreementSigning.getPhone())) {
            throw new ResultCodeException(ResultCode.PHONE_ERROR);
        }
        // 签约人姓名校验
        if (StringUtils.isEmpty(agreementSigning.getSignatory())) {
            throw new ResultCodeException(ResultCode.NAME_IS_NULL);
        }
        // 营业执照
        if (StringUtils.isEmpty(agreementSigning.getBusinessLicense())) {
            throw new ResultCodeException(ResultCode.IMAGE_IS_NULL);
        }
        // 银行卡号校验
        if (!ValidateParam.checkCard(agreementSigning.getAccount())) {
            throw new ResultCodeException(ResultCode.CARD_CODE_ERROR);
        }
        // 货款金额
        if (agreementSigning.getSigningAmount().compareTo(amount) < 0) {
            throw new ResultCodeException(ResultCode.MIN_MONEY);
        }
        // 商家/门店校验
    }

    @Override
    public BaseResp examine(Long id, Byte status, String reason) {
        BaseResp baseResp = new BaseResp();
        try {
            AgreementSigning agreementSigning = agreementSigningMapper.findOneById(id);
            if (agreementSigning == null) {
                throw new ResultCodeException(ResultCode.DETAILS_IS_NOT_NULL);
            }
            if (status == 3 && StringUtils.isEmpty(reason)) {
                throw new ResultCodeException(ResultCode.REMARK_IS_NOT_NULL);
            }
            agreementSigning.setReason(reason);
            agreementSigning.setStatus(status);
            agreementSigning.setUpdated(new Date());
            agreementSigningMapper.examine(agreementSigning);

            // 加入定时任务
            agreementSigningTask.addTask(agreementSigning);
        } catch (ResultCodeException e) {
            baseResp.setResultCode(e.getResultCode());
        }
        return baseResp;
    }

    @Override
    public BaseResp deleteAgreement(Long id) {
        BaseResp baseResp = new BaseResp();
        AgreementSigning agreementSigning = agreementSigningMapper.findOneById(id);
        try {
            if (agreementSigning == null) {
                throw new ResultCodeException(ResultCode.DETAILS_IS_NOT_NULL);
            }
            agreementSigningMapper.deleteAgreementById(id);
        } catch (ResultCodeException e) {
            baseResp.setResultCode(e.getResultCode());
        }
        return baseResp;
    }

    @Override
    public ResultData<BasePageResp<AgreementSigningVo>> agreementList(AgreementSigningReq agreementSigningReq) {
        Page page = PageHelper.startPage(agreementSigningReq.getPageNo(), agreementSigningReq.getPageSize());
        agreementSigningReq.setDeleted(false);
        List<AgreementSigningVo> vo = agreementSigningMapper.findAll(agreementSigningReq);
        return PageHelpUtil.buildPage(vo, page);
    }

    @Override
    public void closeAgreementSigning(AgreementSigning agreementSigning) {
        agreementSigning.setDeleted(true);
        agreementSigning.setExpired(true);
        agreementSigning.setUpdated(new Date());
        agreementSigningMapper.save(agreementSigning);
    }

    public void test() {
        Lock lock = LockCenter.getLock(AgreementSigning.class);
        try {
            // 用来尝试获取锁，但是该方法是有返回值的，
            // 如果获取成功，则返回true，
            // 如果获取失败（即锁已被其他线程获取），则返回false，
            // 也就说这个方法无论如何都会立即返回，在拿不到锁时也不会一直在那等待。
            if (lock.tryLock(3, TimeUnit.SECONDS)) {

            }
        } catch (InterruptedException e) {
            logger.error("分布式锁{}获取失败", lock.getClass());
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
    }

    @Override
    public List<AgreementSigningVo> findAll(AgreementSigningReq req) {
        List<AgreementSigningVo> vos = agreementSigningMapper.findAll(req);
        return vos;
    }
}
